﻿
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using System.Runtime.Serialization;
namespace WCYCReader.Utility
{
    public class CustomBinarySerializer
    {
        private Type serializableObjectType;
        private List<PropertyInfo> serializableProperties = new List<PropertyInfo>();

        public CustomBinarySerializer(Type objectType)
        {
            this.serializableObjectType = objectType;
            this.serializableProperties = this.GetMarkedProperties(objectType);
        }

        private List<PropertyInfo> GetMarkedProperties(Type type)
        {
            return (from property in type.GetProperties()
                where (from x in property.GetCustomAttributes(true)
                    where x is DataMemberAttribute
                    select x).Count<object>() > 0
                select property).ToList<PropertyInfo>();
        }

        private List<int> ReadIntegerList(BinaryReader br)
        {
            List<int> list = new List<int>();
            for (int i = br.ReadInt32(); i > 0; i--)
            {
                list.Add(br.ReadInt32());
            }
            return list;
        }

        public object ReadObject(Stream stream)
        {
            if (stream == null)
            {
                return null;
            }
            BinaryReader br = new BinaryReader(stream);
            object obj2 = Activator.CreateInstance(this.serializableObjectType);
            foreach (PropertyInfo info in this.serializableProperties)
            {
                if (info.PropertyType == typeof(string))
                {
                    info.SetValue(obj2, br.ReadString(), null);
                }
                else if (info.PropertyType == typeof(List<int>))
                {
                    info.SetValue(obj2, this.ReadIntegerList(br), null);
                }
            }
            return obj2;
        }

        private void WriteIntegerList(BinaryWriter bw, List<int> list)
        {
            Action<int> action = null;
            if ((list == null) || !list.Any<int>())
            {
                bw.Write(0);
            }
            else
            {
                bw.Write(list.Count);
                if (action == null)
                {
                    action = x => bw.Write(x);
                }
                list.ForEach(action);
            }
        }

        public void WriteObject(Stream stream, object graph)
        {
            if ((stream != null) && (graph != null))
            {
                BinaryWriter bw = new BinaryWriter(stream);
                foreach (PropertyInfo info in this.serializableProperties)
                {
                    object obj2 = info.GetValue(graph, null);
                    if (info.PropertyType == typeof(string))
                    {
                        bw.Write((obj2 as string) ?? string.Empty);
                    }
                    else if (info.PropertyType == typeof(List<int>))
                    {
                        this.WriteIntegerList(bw, obj2 as List<int>);
                    }
                }
            }
        }
    }
}

